package com.fingard.dsp.bank.directbank.jhbank01;

import org.apache.commons.lang3.StringUtils;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.directbank.jhbank01.utils.PublickeyEncript;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.MD5SaltHelper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * Created by F on 2018/7/20.
 */
public class JHBANK01SinglePay extends JHBANK01Base implements ISinglePay {
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        try {
            detail.reqSeqID = p_req1908.singleDetail.askNumber;
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            JHBANK01Header header = new JHBANK01Header();
            header.userid = bankFront.operator;
            String nodeNo = getBankConfig().getValueAsString("nodeNo");
            header.brchno = nodeNo;
            header.servtp = "";
            header.prcscd = "QCB01";
            writeCommenHeader(xmlTextWriter, header);
            XElement body = new XElement("Body", "");
            body.addChild(new XElement("tellNo", bankFront.operator));//操作员号
            body.addChild(new XElement("nodeNo", nodeNo));// 财政局标示
            body.addChild(new XElement("tranCode", "QCB01"));//交易代码
            //系统简称 6为日期+8位流水
            String transferFlowNo;
            if ("88883".equals(nodeNo)) {
                transferFlowNo = "pj" + Format.Date6Format.format(Format.Date10Format.parse(p_req1908.singleDetail.payDate));
            } else if ("88884".equals(nodeNo)) {
                transferFlowNo = "dy" + Format.Date6Format.format(Format.Date10Format.parse(p_req1908.singleDetail.payDate));

            } else {
                throw new Exception("nodeno属性标签配置有误:" + nodeNo);
            }
            int flowLength = p_req1908.singleDetail.askNumber.length();
            if (flowLength > 8) {
                transferFlowNo = transferFlowNo + p_req1908.singleDetail.askNumber.substring(flowLength - 8);
            } else {
                transferFlowNo = transferFlowNo + StringUtils.leftPad(p_req1908.singleDetail.askNumber, 8, "0");
            }
            body.addChild(new XElement("transferFlowNo", transferFlowNo));// 财政流水号
            body.addChild(new XElement("payAccount", p_req1908.singleDetail.payAct));// 付款账号
            body.addChild(new XElement("payAccountNm", p_req1908.singleDetail.payName));// 付款方户名
            String payAcctBrn = getBankConfig().getValueAsString("org");
            body.addChild(new XElement("payAcctBrn", payAcctBrn));// 付款账户开户机构
            String cur = convertCurToBank(p_req1908.singleDetail.payCur);
            body.addChild(new XElement("currencyType", cur));
            String recAccount = p_req1908.singleDetail.recAct;
            body.addChild(new XElement("recAccount", recAccount));// 收方账户
            String recAccountName = p_req1908.singleDetail.recName;
            body.addChild(new XElement("recAccountName", recAccountName));// 收款方户名
            String recOpenBrn = p_req1908.singleDetail.cnapsCode;
            body.addChild(new XElement("recOpenBrn", recOpenBrn));// 收款方开户行行号
            String recOpenBrnName = p_req1908.singleDetail.cnapsName;
            body.addChild(new XElement("recOpenBrnName", recOpenBrnName));// 收款方开户行行名
            body.addChild(new XElement("recBrn", recOpenBrn));// 接收行号
            body.addChild(new XElement("recBrnName", recOpenBrnName));// 接受行名
            String transferAmt = p_req1908.singleDetail.payAmount;
            body.addChild(new XElement("transferAmt", transferAmt));// 交易金额
            body.addChild(new XElement("payUse", p_req1908.singleDetail.purpose));// 事由
            //是否加急
            body.addChild(new XElement("transferWay", p_req1908.singleDetail.paySpd));// 处理方式
            String tranType;
            if ("1".equals(p_req1908.singleDetail.sameBnk)) {
                tranType = "00";
            } else {
                //默认大额支付
                tranType = "12";
            }
            body.addChild(new XElement("tranType", tranType));
            body.addChild(new XElement("payFee", ""));// 手续费
            body.addChild(new XElement("nextDayFlag", ""));// 次日到账标志
            //付款账号，付款方户名 付款账户开户机构 币种 收款账号 收款方户名
            //收款方开户行行号 收款方开户行名 接收行行号 接收行名 交易金额 交易类型
            String plain = p_req1908.singleDetail.payAct + p_req1908.singleDetail.payName + payAcctBrn +
                    cur + recAccount + recAccountName + recOpenBrn + recOpenBrnName + recOpenBrn + recOpenBrnName + transferAmt + tranType;
            String sign = MD5SaltHelper.md5Hex(plain);
            body.addChild(new XElement("MD5", sign));//
            nodeAnalysis(p_req1908.singleDetail.srcXElement, body, getCharset());
            xmlTextWriter.writeXElement(body);
            xmlTextWriter.writeEndDocument();
            String[] bankResult = sendToBank(xmlTextWriter.toXmlString());
            if (bankResult[0].length() == 0) {
                StringBuilder tmpsbMsg = new StringBuilder();
                XmlTextReader tmpbkReader = loadBankRespXmlReader(bankResult[1], tmpsbMsg);
                if (tmpbkReader != null) {
                    int offset = bankResult[1].indexOf("<hostReturnCode>");
                    int endset = bankResult[1].indexOf("</hostReturnCode>") + "</hostReturnCode>".length();
                    String source = bankResult[1].substring(offset, endset);
                    offset = bankResult[1].indexOf("<hostErrorMessage>");
                    endset = bankResult[1].indexOf("</hostErrorMessage>") + "</hostErrorMessage>".length();
                    source = source + bankResult[1].substring(offset, endset);
                    String hostReturnEncrypt = tmpbkReader.getFirstText("/root/hostReturnEncrypt");
                    boolean b = PublickeyEncript.checkSign(source, hostReturnEncrypt, getBankConfig().getValueAsString("certificatePath"));

                    if (!b) {
                        detail.respCode = "-1";
                        detail.respInfo = "验签不通过";

                    } else {
                        String hostReturnCode = tmpbkReader.getFirstText("/root/hostReturnCode");
                        if ("0000".equals(hostReturnCode)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpbkReader.getFirstText("/root/hostErrorMessage");
                            detail.transState = hostReturnCode;
                            detail.payInfoCode = hostReturnCode;
                            detail.outTransID = tmpbkReader.getFirstText("/root/coreFlowNo");
                        } else {
                            detail.respCode = "-1";
                            detail.respInfo = tmpbkReader.getFirstText("/root/hostErrorMessage");
                        }
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = tmpsbMsg.toString();
                }
            } else if (bankResult[0].equals(ConnState.FAIL)) {
                detail.respCode = "0";
                detail.respInfo = bankResult[1];
                detail.reqSeqID = p_req1908.singleDetail.askNumber;
                detail.transState = PaymentState.FAIL_Payment;
                detail.payInfoCode = bankResult[0];
            } else {
                detail.respCode = "-1";
                detail.respInfo = bankResult[1];
            }

        } catch (Exception ex) {
            detail.respCode = "-1";
            detail.respInfo = ex.getMessage();
            ex.printStackTrace();
        }
        retAts.writeRetDetail(detail);
        return retAts;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        try {
            detail.reqSeqID = p_req1944.askNumber;
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            JHBANK01Header header = new JHBANK01Header();
            header.userid = bankFront.operator;
            String nodeNo = getBankConfig().getValueAsString("nodeNo");
            header.brchno = nodeNo;
            header.servtp = "";
            header.prcscd = "QCA04";
            writeCommenHeader(xmlTextWriter, header);
            xmlTextWriter.writeStartElement("Body");
            xmlTextWriter.writeElementString("tellNo", bankFront.operator, true);
            xmlTextWriter.writeElementString("nodeNo", nodeNo, true);
            xmlTextWriter.writeElementString("tranCode", "QCA04", true);

            String transferFlowNo;
            if ("88883".equals(nodeNo)) {
                transferFlowNo = "pj" + Format.Date6Format.format(Format.DateTimeFormat.parse(p_req1944.bgnDate));
            } else if ("88884".equals(nodeNo)) {
                transferFlowNo = "dy" + Format.Date6Format.format(Format.DateTimeFormat.parse(p_req1944.bgnDate));

            } else {
                throw new Exception("nodeno属性标签配置有误:" + nodeNo);
            }
            int flowLength = p_req1944.askNumber.length();
            if (flowLength > 8) {
                transferFlowNo = transferFlowNo + p_req1944.askNumber.substring(flowLength - 8);
            } else {
                transferFlowNo = transferFlowNo + StringUtils.leftPad(p_req1944.askNumber, 8, "0");
            }
            xmlTextWriter.writeElementString("transferFlowNo", transferFlowNo, true);
            xmlTextWriter.writeEndDocument();
            String[] bankResult = sendToBank(xmlTextWriter.toXmlString());
            if (bankResult[0].length() == 0) {
                StringBuilder tmpsbMsg = new StringBuilder();
                XmlTextReader tmpbkReader = loadBankRespXmlReader(bankResult[1], tmpsbMsg);
                if (tmpbkReader != null) {
                    int offset = bankResult[1].indexOf("<hostReturnCode>");
                    int endset = bankResult[1].indexOf("</hostReturnCode>") + "</hostReturnCode>".length();
                    String source = bankResult[1].substring(offset, endset);
                    offset = bankResult[1].indexOf("<hostErrorMessage>");
                    endset = bankResult[1].indexOf("</hostErrorMessage>") + "</hostErrorMessage>".length();
                    source = source + bankResult[1].substring(offset, endset);
                    String hostReturnEncrypt = tmpbkReader.getFirstText("/root/hostReturnEncrypt");
                    boolean b = PublickeyEncript.checkSign(source, hostReturnEncrypt, getBankConfig().getValueAsString("certificatePath"));
                    if (!b) {
                        detail.respCode = "-1";
                        detail.respInfo = "验签不通过";

                    } else {
                        String hostReturnCode = tmpbkReader.getFirstText("/root/hostReturnCode");
                        String retMsg = tmpbkReader.getFirstText("/root/remark");
                        if (StringHelper.isNullOrEmpty(retMsg)) {
                            retMsg = tmpbkReader.getFirstText("/root/hostErrorMessage");
                        }
                        if ("0000".equals(hostReturnCode)) {
                            detail.respCode = "0";
                            detail.respInfo = retMsg;//tmpbkReader.getFirstText("/root/remark");
                            detail.transState = tmpbkReader.getFirstText("/root/transt");
                            detail.payInfoCode = detail.transState;
                            detail.outTransID = tmpbkReader.getFirstText("/root/coreFlowNo");
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = retMsg;//tmpbkReader.getFirstText("/root/hostErrorMessage");
                            detail.transState = hostReturnCode + "+" + tmpbkReader.getFirstText("/root/transt");
                            detail.payInfoCode = detail.transState;
                        }
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = tmpsbMsg.toString();
                }
            } else {
                detail.respCode = "-1";
                detail.respInfo = bankResult[1];
            }
        } catch (Exception ex) {
            detail.respCode = "-1";
            detail.respInfo = ex.getMessage();
            ex.printStackTrace();
        }
        retAts.writeRetDetail(detail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
